package common

import (
	"commerce/cache"
	"commerce/vo"
	"encoding/json"
	"github.com/go-sql-driver/mysql"
	"github.com/gomodule/redigo/redis"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"time"
)

type (
	configuration struct {
		SqlConfig     mysql.Config
		Server        string
		ImgUploadPath string
		CookieDomain  string
		OssConfig     ossConfig
		RedisConfig   redisConfig
		LogConfig     logConfig
	}

	ossConfig struct {
		Endpoint        string
		AccessKeyId     string
		AccessKeySecret string
		BucketName      string
	}

	redisConfig struct {
		MaxIdle     int
		MaxActive   int
		IdleTimeout int
		Addr        string
		Db          int
		Pwd         string
	}

	logConfig struct {
		FileName    string // 日志文件名称
		MaxBytes    uint   // 日志文件rolleover前最大字节
		BackUpCount uint8  // 备份文件个数
	}

	appError struct {
		Error      string `json:"error"`
		Message    string `json:"message"`
		HttpStatus int    `json:"status"`
		Data       interface{}
	}

	TokenError struct {
		ErrNo int `json:"errno"`
	}

	errorResource struct {
		Data appError `json:"data"`
	}
)

var AppConfig configuration

func initConfig() {

	loadAppConfig()
}

func loadAppConfig() {

	file, err := os.Open(filepath.Join(CurDir, "common/config.json"))
	if err != nil {
		log.Fatalf("[loadConfig]:%s\n", err)
	}
	defer file.Close()

	AppConfig = configuration{}
	err = json.NewDecoder(file).Decode(&AppConfig)
	if err != nil {
		log.Fatalf("[loadAppConfig]:%s\n", err)
	}
	initDBConfig()

	initRedisConfig(AppConfig.RedisConfig)

	InitLog()
}

func initRedisConfig(config redisConfig) {

	cache.Pool = &redis.Pool{
		MaxIdle:     config.MaxIdle,
		MaxActive:   config.MaxActive,
		IdleTimeout: time.Duration(config.IdleTimeout),
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", config.Addr,
				redis.DialDatabase(config.Db),
				redis.DialPassword(config.Pwd),
			)
		},
	}
}

func DisplayAppErr(w http.ResponseWriter, handlerError error, message string, code int) {

	errObj := appError{
		Error:      handlerError.Error(),
		Message:    message,
		HttpStatus: code,
	}
	Error.Printf("[DisplayAppError]:%s\n", handlerError)

	w.Header().Set("Content-Type", "application/json;charset=utf-8")
	w.WriteHeader(code)
	if j, err := json.Marshal(errorResource{Data: errObj}); err == nil {
		w.Write(j)
	}
}

func DisplayOk(w http.ResponseWriter, message string, code int) {

	errObj := appError{
		Message:    message,
		HttpStatus: code,
	}
	w.Header().Set("Content-Type", "application/json;charset=utf-8")
	w.WriteHeader(code)
	if j, err := json.Marshal(errorResource{Data: errObj}); err == nil {
		w.Write(j)
	}
}

func DisplayTokenErr(w http.ResponseWriter, code int) {

	w.Header().Set("Content-Type", "application/json;charset=utf-8")
	w.WriteHeader(http.StatusOK)

	if j, err := json.Marshal(vo.Ok2(TokenError{code})); err == nil {
		w.Write(j)
	}
}
